package cn.itsource.basic.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.itsource.basic.exception.BusinessException;
import cn.itsource.basic.service.IVerifyCodeService;
import cn.itsource.basic.util.AjaxResult;
import cn.itsource.basic.util.StrUtils;
import cn.itsource.basic.util.VerifyCodeUtils;
import cn.itsource.user.domain.User;
import cn.itsource.user.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class VerifyCodeServiceImpl implements IVerifyCodeService {

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private UserMapper userMapper;

    /** 获取图形验证码 */
    @Override
    public AjaxResult getImageCode(String key) {
        //生成验证码
        String code = StrUtils.getComplexRandomString(4);
        //添加到redis，并且设置过期时间 - 5分钟
        redisTemplate.opsForValue().set(key,code,5, TimeUnit.MINUTES);
        //将验证码合并到图片，并用base64编码为base64的字符串
        String base64Str = VerifyCodeUtils.verifyCode(115, 40, code);
        //返回给前端
        return AjaxResult.me().setResultObj(base64Str);
    }

    /** 获取手机验证码 */
    @Override
    public AjaxResult getSmsCode(Map<String, String> map) {
        //获取到前端输入的值
        String phone = map.get("phone");
        String imageCode = map.get("imageCode");
        String imageCodeKey = map.get("imageCodeKey");
        //空值校验
        if (StrUtil.isBlank(phone)){
            throw new BusinessException("手机号码不能为空！");
        }
        if (StrUtil.isBlank(imageCode)){
            throw new BusinessException("图形验证码不能为空！");
        }
        //图形验证码校验 - 图形验证码是否过期，是否正确
        Object obj = redisTemplate.opsForValue().get(imageCodeKey);
        if (obj == null){
            throw new BusinessException("图形验证码已过期！");
        }
        if (!obj.toString().equalsIgnoreCase(imageCode)){
            throw new BusinessException("图形验证码错误！");
        }
        //手机号码是否已经注册过
        User user = userMapper.findByPhone(phone);
        if (user != null){
            throw new BusinessException("该手机号码已注册过！");
        }

        //生成手机验证码
        //从redis获取手机验证码：key【业务键:手机号】
        // 加业务键是为了防止不止是用在验证码，如果是其他的业务要使用redis可以区分
        Object phoneCode = redisTemplate.opsForValue().get("register:" + phone);
        String code = null;//用于保存手机验证码
        // 如果redis没有：第一次获取验证码或者过期了，重新发送
        if (phoneCode == null){
            code = StrUtils.getRandomString(6);
        }else {
            // 如果redis有：验证码没有过期，判断是否过了重发时间
            //获取之前的验证码设置的时间戳
            long oldTime = Long.parseLong(phoneCode.toString().split(":")[1]);
            //获取当前时间
            long newTime = System.currentTimeMillis();
            //没有过重发时间
            if ((newTime - oldTime) < 1*60*1000){
                throw new BusinessException("请勿频繁操作！");
            }else {
                //过了重发时间 - 发之前的验证码
                code = phoneCode.toString().split(":")[0];
            }
        }
        //将验证码保存到redis - 并设置三分钟有效
        //"register:" + phone：加业务键是为了防止不止是用在验证码，如果是其他的业务要使用redis可以区分
        //code+":"+System.currentTimeMillis()：为了在上面判断是否过了重发时间，所以加上当前时间，当前时间就是发送短信的时间
        redisTemplate.opsForValue().set("register:" + phone,code + ":" +
                System.currentTimeMillis(),3,TimeUnit.MINUTES);
        //调用工具类发送短信
        //SmsUtils.sendSms(phone,"您的验证码为：" + code + "，强盛集团提示您请在三分钟内使用！");
        System.out.println("您的验证码为：" + code + "，强盛集团提示您请在三分钟内使用！");
        return new AjaxResult();
    }

    /** 微信绑定发送验证码 */
    @Override
    public AjaxResult getBinderSmsCode(Map<String, String> map) {
        //获取到前端输入的值
        String phone = map.get("phone");
        //空值校验
        if (StrUtil.isBlank(phone)){
            throw new BusinessException("手机号码不能为空！");
        }

        //生成手机验证码
        //从redis获取手机验证码：key【业务键:手机号】
        // 加业务键是为了防止不止是用在验证码，如果是其他的业务要使用redis可以区分
        Object phoneCode = redisTemplate.opsForValue().get("binder:" + phone);
        String code = null;//用于保存手机验证码
        // 如果redis没有：第一次获取验证码或者过期了，重新发送
        if (phoneCode == null){
            code = StrUtils.getRandomString(6);
        }else {
            // 如果redis有：验证码没有过期，判断是否过了重发时间
            //获取之前的验证码设置的时间戳
            long oldTime = Long.parseLong(phoneCode.toString().split(":")[1]);
            //获取当前时间
            long newTime = System.currentTimeMillis();
            //没有过重发时间
            if ((newTime - oldTime) < 1*60*1000){
                throw new BusinessException("请勿频繁操作！");
            }else {
                //过了重发时间 - 发之前的验证码
                code = phoneCode.toString().split(":")[0];
            }
        }
        //将验证码保存到redis - 并设置三分钟有效
        //"register:" + phone：加业务键是为了防止不止是用在验证码，如果是其他的业务要使用redis可以区分
        //code+":"+System.currentTimeMillis()：为了在上面判断是否过了重发时间，所以加上当前时间，当前时间就是发送短信的时间
        redisTemplate.opsForValue().set("binder:" + phone,code + ":" +
                System.currentTimeMillis(),3,TimeUnit.MINUTES);
        //调用工具类发送短信
        //SmsUtils.sendSms(phone,"您的验证码为：" + code + "，强盛集团提示您请在三分钟内使用！");
        System.out.println("您的验证码为：" + code + "，强盛集团提示您请在三分钟内使用！");
        return new AjaxResult();
    }
}
